# Enuminate the index of net mess list
I_NR,I_LASTRECV,I_MESS_FROM,I_MESS_TO,I_RPC,I_ARGS = range(6)


class NetMessage:
    lastrecv = 0 # should be set the last recieved 
    nr = 0
    def __init__(self,mess_from,mess_to):
        self.mess_from = mess_from
        self.mess_to = mess_to
    def _getHeader(self):
        return [self.nr,self.lastrecv,self.mess_from,self.mess_to]
    def getList(self):
        raise NotImplementedError('This is an abstract class, implement this in subclass')


class NetMessPing(NetMessage):
    def __init__(self,m_from,m_to):
        NetMessage.__init__(self,m_from, m_to)
    def doAction(self,callback):
        callback.ping(self.mess_from)
    def getList(self):
        return self._getHeader() + ['ping',self.mess_from]

# Hand shake Messages
class NetMessAddPeer(NetMessage):
    def __init__(self,addr):
        NetMessage.__init__(self,None,None)
        self.addr = addr
    def doAction(self,callback):
        callback.addPeer(self.addr)
    def getList(self):
        return self._getHeader() + ['addPeer',self.addr]

class NetMessSetPeerId(NetMessage):
    def __init__(self,m_from,m_to,id):
        NetMessage.__init__(self,m_from, m_to)
        self.id = id
    def doAction(self,callback):
        callback.setPeerId(self.id)
    def getList(self):
        return self._getHeader() + ['setPeerId',self.id]

class NetMessPeerReady(NetMessage):
    ' tells server peer is ready to listen '
    def __init__(self,m_from):
        NetMessage.__init__(self,m_from,None)
    def doAction(self,callback):
        callback.peerReady(self.mess_from)
    def getList(self):
        return self._getHeader() + ['peerReady',self.mess_from]

class NetMessPeerRunningGE(NetMessage):
    ' tells peer we are running game engine '
    def __init__(self,m_from):
        NetMessage.__init__(self,m_from,None)
    def doAction(self,callback):
        callback.peerRunningGE(self.mess_from)
    def getList(self):
        return self._getHeader() + ['peerRunningGE',self.mess_from]

class NetMessGameStart(NetMessage):
    ' Send start game to GameSystem.'
    def __init__(self,m_from, map_name ):
        NetMessage.__init__(self,m_from, None)
        self.map_name = map_name

    def doAction(self,callback):
        callback.startGame(self.mess_from,self.map_name)
    def getList(self):
        return self._getHeader() + ['startGame',self.mess_from,self.map_name]

class NetMessGameStop(NetMessage):
    ' Send stop game to GameSystem.'
    def __init__(self,m_from):
        NetMessage.__init__(self,m_from, None)

    def doAction(self,callback):
        callback.stopGame(self.mess_from)
    def getList(self):
        return self._getHeader() + ['stopGame',self.mess_from]

class NetMessDisconnect(NetMessage):
    ' Send stop game to GameSystem.'
    def __init__(self,m_from):
        NetMessage.__init__(self,m_from, None)

    def doAction(self,callback):
        callback.disconnect(self.mess_from)
    def getList(self):
        return self._getHeader() + ['disconnect',self.mess_from]


# Game Engine event messages
class NetMessAddPlayer(NetMessage):
    def __init__(self,m_from,m_to, player ):
        NetMessage.__init__(self,m_from, m_to)
        self.player_args = [player.sprite.pos_x,player.sprite.pos_y,
                            player.sprite.vel_x,player.sprite.vel_y,
                            player.name,player.id,player.sprite.id]

    def doAction(self,callback):
        callback.addPlayer(self.mess_from,self.player_args)
    def getList(self):
        return self._getHeader() + ['addPlayer',self.mess_from,self.player_args]

class NetMessRemovePlayer(NetMessage):
    def __init__(self,m_from,m_to, player ):
        NetMessage.__init__(self,m_from, m_to)
        self.player_id = player.id
    def doAction(self,callback):
        callback.removePlayer(self.mess_from,self.player_id)
    def getList(self):
        return self._getHeader() + ['removePlayer',self.mess_from,self.player_id]

class NetMessRespawnPlayer(NetMessage):
    def __init__(self,m_from,m_to, player_id ):
        NetMessage.__init__(self,m_from, m_to)
        self.player_id = player_id
    def doAction(self,callback):
        callback.respawnPlayer(self.player_id)
    def getList(self):
        return self._getHeader() + ['respawnPlayer',self.player_id]

##class NetMessAddShip(NetMessage):
##    def __init__(self,m_from,m_to, args ):
##        NetMessage.__init__(self,m_from, m_to)
##        self.args = args
##    def doAction(self,callback):
##        callback.addShip(self.args,local=0)
##    def getList(self):
##        return ['addShip',self.args,{'local':0}]

class NetMessAddShot(NetMessage):
    def __init__(self,m_from,m_to,class_type, args, key_args={} ):
        NetMessage.__init__(self,m_from, m_to)
        self.class_type = class_type
        self.args = args
        self.key_args = key_args
    def doAction(self,callback):
        callback.addShot(self.class_type, self.args,self.key_args)
    def getList(self):
        return self._getHeader() + ['addShot',self.class_type, self.args,self.key_args]

class NetMessRemoveGo(NetMessage):
    def __init__(self,m_from,m_to, go ):
        NetMessage.__init__(self,m_from, m_to)
        self.id = go.id
    def doAction(self,callback):
        callback.removeGo(self.mess_from,self.id)
    def getList(self):
        return self._getHeader() + ['removeGo',self.mess_from,self.id]

class NetMessShipKilled(NetMessage):
    def __init__(self,m_from,m_to, id):
        NetMessage.__init__(self,m_from, m_to)
        self.id = id # GameObject ID
    def doAction(self,callback):
        callback.shipKilled(self.id)
    def getList(self):
        return self._getHeader() + ['shipKilled',self.id]

class NetMessSyncGameObject(NetMessage):
    def __init__(self,m_from,m_to, id, sync_args ):
        NetMessage.__init__(self,m_from, m_to)
        self.sync_args = sync_args
        self.id = id # GameObject ID

    def doAction(self,callback):
        callback.synchGameObject(self.id,self.sync_args)
    def getList(self):
        return self._getHeader() + ['synchGameObject',self.id,self.sync_args]
